<template>
	<view class="merge-table">
		<view class="table-header">
			<view v-for="(col, index) in props.columns" :key="index" class="th" :style="getColumnStyle(col)">
				{{ col.title }}
			</view>
		</view>
		<view class="table-body">
			<view v-for="(row, rowIndex) in props.data" :key="rowIndex" class="tr">
				<view v-for="(col, colIndex) in props.columns" :key="colIndex" class="td-wrapper"
					:style="getColumnStyle(col)">
					<view v-if="shouldShowCell(rowIndex, col.key)" class="td"
						:class="{ 'td-merged': isMerged(rowIndex, col.key) }" :style="getCellStyle(rowIndex, col.key)">
						{{ row[col.key] }}
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
	import { ref, computed } from 'vue'

	interface Column {
		title : string
		key : string
		width ?: string | number // 新增宽度配置，可以是具体数值或百分比
	}

	interface TableData {
		[key : string] : any
	}

	const props = defineProps<{
		columns : Column[]
		data : TableData[]
	}>()

	// 计算总宽度和剩余宽度
	const { totalFixedWidth, remainingColumns } = computed(() => {
		let fixedWidth = 0
		let remaining = 0

		props.columns.forEach(col => {
			if (typeof col.width === 'number') {
				fixedWidth += col.width
			} else if (typeof col.width === 'string' && col.width.endsWith('rpx')) {
				fixedWidth += parseInt(col.width)
			} else {
				remaining++
			}
		})

		return {
			totalFixedWidth: fixedWidth,
			remainingColumns: remaining
		}
	}).value

	// 获取列样式
	const getColumnStyle = (column : Column) => {
		if (column.width) {
			// 如果指定了宽度，直接使用
			return {
				width: typeof column.width === 'number' ? `${column.width}rpx` : column.width
			}
		} else {
			// 如果没有指定宽度，平均分配剩余空间
			const remainingWidth = remainingColumns > 0
				? `${(100 - (totalFixedWidth / 10)) / remainingColumns}%`
				: `${100 / props.columns.length}%`
			return {
				width: remainingWidth
			}
		}
	}

	// 计算每列的合并信息
	const columnMerges = computed(() => {
		const merges : Record<string, Record<number, number>> = {}

		props.columns.forEach(col => {
			merges[col.key] = {}
			let currentValue = props.data[0][col.key]
			let startIndex = 0
			let span = 1

			for (let i = 1; i <= props.data.length; i++) {
				if (i === props.data.length || props.data[i][col.key] !== currentValue) {
					if (span > 1) {
						merges[col.key][startIndex] = span
					}
					if (i < props.data.length) {
						currentValue = props.data[i][col.key]
						startIndex = i
						span = 1
					}
				} else {
					span++
				}
			}
		})

		return merges
	})

	// 判断是否显示单元格
	const shouldShowCell = (rowIndex : number, key : string) => {
		const merges = columnMerges.value[key]

		if (merges[rowIndex]) {
			return true
		}

		for (let i = rowIndex - 1; i >= 0; i--) {
			if (merges[i]) {
				const span = merges[i]
				if (i + span > rowIndex) {
					return false
				}
				break
			}
		}

		return true
	}

	// 判断是否是合并单元格
	const isMerged = (rowIndex : number, key : string) => {
		const merges = columnMerges.value[key]
		return !!merges[rowIndex]
	}

	// 获取单元格样式
	const getCellStyle = (rowIndex : number, key : string) => {
		const style : Record<string, string> = {
			width: '100%'
		}

		const merges = columnMerges.value[key]
		const span = merges[rowIndex]

		if (span) {
			style.height = `${span * 44}px`
			style.position = 'absolute'
			style.left = '0'
			style.top = '0'
			style.right = '0'
		}

		return style
	}
</script>

<style scoped>
	.merge-table {
		width: 100%;
		border: 1rpx solid #eee;
		box-sizing: border-box;
		font-size: 24rpx;
	}

	.table-header {
		display: flex;
		background-color: #f6f7fb;
	}

	.th {
		padding: 20rpx;
		text-align: center;
		font-weight: bold;
		border-right: 1rpx solid #eee;
		box-sizing: border-box;
		background-color: #f5f5f5;
	}

	.tr {
		display: flex;
		border-bottom: 1rpx solid #eee;
		min-height: 44px;
	}

	.td-wrapper {
		position: relative;
		border-right: 1rpx solid #eee;
		box-sizing: border-box;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.td {
		padding: 10rpx 20rpx;
		text-align: left;
		box-sizing: border-box;
		display: flex;
		align-items: left;
		justify-content: left;
		background-color: #fff;
		min-height: 44px;
		width: 100%;
	}

	.td-merged {
		/* border: 1rpx solid #eee; */
		border-top: none;
	}

	.th:last-child,
	.td-wrapper:last-child {
		border-right: none;
	}
</style>